package com.yt.lxh.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.yt.lxh.common.utils.RandomUtil;
import com.yt.lxh.constant.WxPayConstant;
import com.yt.lxh.payment.config.WxPayConfig;
import com.yt.lxh.payment.service.PaymentService;
import com.yt.lxh.payment.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class WxPayServiceImpl implements WxPayService, PaymentService {

    @Autowired
    private WxPayConfig wxPayConfig;

    @Autowired
    private CloseableHttpClient wxPayClient;

    /**
     * native 统一支付
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> nativePay() throws IOException {
        // TODO: 2023/11/22 生成支付订单，存入数据库
        // JSAPI下单
        HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxPayConstant.NATIVE_PAY));
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("appid", wxPayConfig.getAppid());
        reqMap.put("mchid", wxPayConfig.getMchId());
        reqMap.put("description", "商品描述");
        reqMap.put("out_trade_no", RandomUtil.createId());
        reqMap.put("notify_url", wxPayConfig.getNotifyDomain());
        HashMap<String, Object> amount = new HashMap<>();
        amount.put("total", 100);
        amount.put("currency", "CNY");
        reqMap.put("amount", amount);
        log.info("请求体，{}", JSON.toJSONString(reqMap));
        StringEntity entity = new StringEntity(JSON.toJSONString(reqMap), "utf-8");
        httpPost.setEntity(entity);
        return pay(httpPost);
    }

    /**
     * jsapi 统一支付
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> jsapiPay() throws IOException {
        // TODO: 2023/11/22 生成支付订单，存入数据库
        HttpPost httpPost = new HttpPost(wxPayConfig.getDomain().concat(WxPayConstant.JSAPI_PAY));
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("appid", wxPayConfig.getAppid());
        reqMap.put("mchid", wxPayConfig.getMchId());
        reqMap.put("description", "商品描述");
        reqMap.put("out_trade_no", RandomUtil.getOrderOn());
        reqMap.put("notify_url", wxPayConfig.getNotifyDomain());
        HashMap<String, Object> amount = new HashMap<>();
        amount.put("total", 100);
        amount.put("currency", "CNY");
        reqMap.put("amount", amount);
        HashMap<String, Object> payer = new HashMap<>();
        payer.put("openid", "1756576");
        reqMap.put("payer", payer);
        log.info("请求体，{}", JSON.toJSONString(reqMap));
        StringEntity entity = new StringEntity(JSON.toJSONString(reqMap), "utf-8");
        httpPost.setEntity(entity);
        pay(httpPost);
        //返回二维码的地址
        return null;
    }

    @Override
    public Map<String, Object> pay(HttpRequestBase httpRequest) throws IOException {
        CloseableHttpResponse response = null;
        try {
            //完成签名并执行请求
            response = wxPayClient.execute(httpRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            //成功
            if (statusCode == 200) {
                HashMap hashMap = JSON.parseObject(responseBody, HashMap.class);
                log.info("响应成功，返回结果为：{}", hashMap.get("code_url"));
            } else {
                if (statusCode != 204) {
                    log.error("响应失败，返回结果为：{}", responseBody);
                    return null;
                }
            }
        } catch (Exception e) {

        } finally {
            if (response != null) response.close();
        }
        //返回二维码的地址
        return null;
    }

    /**
     * 查询支付状态
     * @param orderNo 订单号
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> queryPayStatus(String orderNo) throws IOException {
        // 请求构造
        String httpUrl = wxPayConfig.getDomain().concat(
                String.format(WxPayConstant.ORDER_QUERY_BY_NO, orderNo, wxPayConfig.getMchId()));
        HttpGet httpGet = new HttpGet(httpUrl);
        // 设置请求头
        httpGet.addHeader("Accept","application/json");
        //完成签名并执行请求
        CloseableHttpResponse response = wxPayClient.execute(httpGet);
        Map<String, Object> resMap = null;
        try{
            int statusCode = response.getStatusLine().getStatusCode();
            String responseBody = EntityUtils.toString(response.getEntity());
            resMap = JSON.parseObject(responseBody, HashMap.class);
            //成功
            if(statusCode<400){
                log.info("查询订单支付{}成功, 响应体：{}", orderNo, resMap);
            }
            //失败
            else{
                log.error("查询订单支付{}失败,返回数据为{}.",orderNo,resMap);
                throw new IOException("订单查询失败");
            }
        }
        finally{
            response.close();
        }
        return resMap;
    }
}
